/****************************************************************************
 * drivers/audio/es8388.h
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.  The
 * ASF licenses this file to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the
 * License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations
 * under the License.
 *
 ****************************************************************************/

#ifndef __DRIVERS_AUDIO_ES8388_H
#define __DRIVERS_AUDIO_ES8388_H

/****************************************************************************
 * Included Files
 ****************************************************************************/

#include <nuttx/config.h>
#include <nuttx/compiler.h>

#include <pthread.h>

#include <nuttx/mqueue.h>
#include <nuttx/wqueue.h>
#include <nuttx/fs/ioctl.h>

#include "esxxxx_common.h"

#ifdef CONFIG_AUDIO

/****************************************************************************
 * Pre-processor Definitions
 ****************************************************************************/

#define ES8388_DAC_CHVOL_DB(v) (2*v/3 + 30)

/* Registers Addresses ******************************************************/

#define ES8388_CONTROL1                0x00
#define ES8388_CONTROL2                0x01
#define ES8388_CHIPPOWER               0x02
#define ES8388_ADCPOWER                0x03
#define ES8388_DACPOWER                0x04
#define ES8388_CHIPLOPOW1              0x05
#define ES8388_CHIPLOPOW2              0x06
#define ES8388_ANAVOLMANAG             0x07
#define ES8388_MASTERMODE              0x08
#define ES8388_ADCCONTROL1             0x09
#define ES8388_ADCCONTROL2             0x0a
#define ES8388_ADCCONTROL3             0x0b
#define ES8388_ADCCONTROL4             0x0c
#define ES8388_ADCCONTROL5             0x0d
#define ES8388_ADCCONTROL6             0x0e
#define ES8388_ADCCONTROL7             0x0f
#define ES8388_ADCCONTROL8             0x10
#define ES8388_ADCCONTROL9             0x11
#define ES8388_ADCCONTROL10            0x12
#define ES8388_ADCCONTROL11            0x13
#define ES8388_ADCCONTROL12            0x14
#define ES8388_ADCCONTROL13            0x15
#define ES8388_ADCCONTROL14            0x16
#define ES8388_DACCONTROL1             0x17
#define ES8388_DACCONTROL2             0x18
#define ES8388_DACCONTROL3             0x19
#define ES8388_DACCONTROL4             0x1a
#define ES8388_DACCONTROL5             0x1b
#define ES8388_DACCONTROL6             0x1c
#define ES8388_DACCONTROL7             0x1d
#define ES8388_DACCONTROL8             0x1e
#define ES8388_DACCONTROL9             0x1f
#define ES8388_DACCONTROL10            0x20
#define ES8388_DACCONTROL11            0x21
#define ES8388_DACCONTROL12            0x22
#define ES8388_DACCONTROL13            0x23
#define ES8388_DACCONTROL14            0x24
#define ES8388_DACCONTROL15            0x25
#define ES8388_DACCONTROL16            0x26
#define ES8388_DACCONTROL17            0x27
#define ES8388_DACCONTROL18            0x28
#define ES8388_DACCONTROL19            0x29
#define ES8388_DACCONTROL20            0x2a
#define ES8388_DACCONTROL21            0x2b
#define ES8388_DACCONTROL22            0x2c
#define ES8388_DACCONTROL23            0x2d
#define ES8388_DACCONTROL24            0x2e
#define ES8388_DACCONTROL25            0x2f
#define ES8388_DACCONTROL26            0x30
#define ES8388_DACCONTROL27            0x31
#define ES8388_DACCONTROL28            0x32
#define ES8388_DACCONTROL29            0x33
#define ES8388_DACCONTROL30            0x34

/* Register Power-up Default Values *****************************************/

#define ES8388_CONTROL1_DEFAULT        0x06
#define ES8388_CONTROL2_DEFAULT        0x5c
#define ES8388_CHIPPOWER_DEFAULT       0xc3
#define ES8388_ADCPOWER_DEFAULT        0xfc
#define ES8388_DACPOWER_DEFAULT        0xc0
#define ES8388_CHIPLOPOW1_DEFAULT      0x00
#define ES8388_CHIPLOPOW2_DEFAULT      0x00
#define ES8388_ANAVOLMANAG_DEFAULT     0x7c
#define ES8388_MASTERMODE_DEFAULT      0x80
#define ES8388_ADCCONTROL1_DEFAULT     0x00
#define ES8388_ADCCONTROL2_DEFAULT     0x00
#define ES8388_ADCCONTROL3_DEFAULT     0x02
#define ES8388_ADCCONTROL4_DEFAULT     0x00
#define ES8388_ADCCONTROL5_DEFAULT     0x06
#define ES8388_ADCCONTROL6_DEFAULT     0x30
#define ES8388_ADCCONTROL7_DEFAULT     0x20
#define ES8388_ADCCONTROL8_DEFAULT     0xc0
#define ES8388_ADCCONTROL9_DEFAULT     0xc0
#define ES8388_ADCCONTROL10_DEFAULT    0x38
#define ES8388_ADCCONTROL11_DEFAULT    0xb0
#define ES8388_ADCCONTROL12_DEFAULT    0x32
#define ES8388_ADCCONTROL13_DEFAULT    0x06
#define ES8388_ADCCONTROL14_DEFAULT    0x00
#define ES8388_DACCONTROL1_DEFAULT     0x00
#define ES8388_DACCONTROL2_DEFAULT     0x06
#define ES8388_DACCONTROL3_DEFAULT     0x22
#define ES8388_DACCONTROL4_DEFAULT     0xc0
#define ES8388_DACCONTROL5_DEFAULT     0xc0
#define ES8388_DACCONTROL6_DEFAULT     0x08
#define ES8388_DACCONTROL7_DEFAULT     0x00
#define ES8388_DACCONTROL8_DEFAULT     0x1f
#define ES8388_DACCONTROL9_DEFAULT     0xf7
#define ES8388_DACCONTROL10_DEFAULT    0xfd
#define ES8388_DACCONTROL11_DEFAULT    0xff
#define ES8388_DACCONTROL12_DEFAULT    0x1f
#define ES8388_DACCONTROL13_DEFAULT    0xf7
#define ES8388_DACCONTROL14_DEFAULT    0xfd
#define ES8388_DACCONTROL15_DEFAULT    0xff
#define ES8388_DACCONTROL16_DEFAULT    0x00
#define ES8388_DACCONTROL17_DEFAULT    0x38
#define ES8388_DACCONTROL18_DEFAULT    0x28
#define ES8388_DACCONTROL19_DEFAULT    0x28
#define ES8388_DACCONTROL20_DEFAULT    0x38
#define ES8388_DACCONTROL21_DEFAULT    0x00
#define ES8388_DACCONTROL22_DEFAULT    0x00
#define ES8388_DACCONTROL23_DEFAULT    0x00
#define ES8388_DACCONTROL24_DEFAULT    0x00
#define ES8388_DACCONTROL25_DEFAULT    0x00
#define ES8388_DACCONTROL26_DEFAULT    0x00
#define ES8388_DACCONTROL27_DEFAULT    0x00
#define ES8388_DACCONTROL28_DEFAULT    0x00
#define ES8388_DACCONTROL29_DEFAULT    0xaa
#define ES8388_DACCONTROL30_DEFAULT    0xaa

/* Register Bit Definitions *************************************************/

/* 0x00 Chip Control 1 */

#define ES8388_VMIDSEL_SHIFT          (0)
#define ES8388_VMIDSEL_BITMASK        (0x03 << ES8388_VMIDSEL_SHIFT)
#define ES8388_VMIDSEL_DISABLE        (0 << ES8388_VMIDSEL_SHIFT)
#define ES8388_VMIDSEL_50K            (1 << ES8388_VMIDSEL_SHIFT)
#define ES8388_VMIDSEL_500K           (2 << ES8388_VMIDSEL_SHIFT)
#define ES8388_VMIDSEL_5K             (3 << ES8388_VMIDSEL_SHIFT)

#define ES8388_ENREF_SHIFT            (2)
#define ES8388_ENREF_BITMASK          (0x01 << ES8388_ENREF_SHIFT)
#define ES8388_ENREF_DISABLE          (0 << ES8388_ENREF_SHIFT)
#define ES8388_ENREF_ENABLE           (1 << ES8388_ENREF_SHIFT)

#define ES8388_SEQEN_SHIFT            (3)
#define ES8388_SEQEN_BITMASK          (0x01 << ES8388_SEQEN_SHIFT)
#define ES8388_SEQEN_DISABLE          (0 << ES8388_SEQEN_SHIFT)
#define ES8388_SEQEN_ENABLE           (1 << ES8388_SEQEN_SHIFT)

#define ES8388_SAMEFS_SHIFT           (4)
#define ES8388_SAMEFS_BITMASK         (0x01 << ES8388_SAMEFS_SHIFT)
#define ES8388_SAMEFS_DIFFER          (0 << ES8388_SAMEFS_SHIFT)
#define ES8388_SAMEFS_SAME            (1 << ES8388_SAMEFS_SHIFT)

#define ES8388_DACMCLK_SHIFT          (5)
#define ES8388_DACMCLK_BITMASK        (0x01 << ES8388_DACMCLK_SHIFT)
#define ES8388_DACMCLK_ADCMCLK        (0 << ES8388_DACMCLK_SHIFT)
#define ES8388_DACMCLK_DACMCLK        (1 << ES8388_DACMCLK_SHIFT)

#define ES8388_LRCM_SHIFT             (6)
#define ES8388_LRCM_BITMASK           (0x01 << ES8388_LRCM_SHIFT)
#define ES8388_LRCM_ISOLATED          (0 << ES8388_LRCM_SHIFT)
#define ES8388_LRCM_ALL               (1 << ES8388_LRCM_SHIFT)

#define ES8388_SCPRESET_SHIFT         (7)
#define ES8388_SCPRESET_BITMASK       (0x01 << ES8388_SCPRESET_SHIFT)
#define ES8388_SCPRESET_NORMAL        (0 << ES8388_SCPRESET_SHIFT)
#define ES8388_SCPRESET_RESET         (1 << ES8388_SCPRESET_SHIFT)

/* 0x01 Chip Control 2 */

#define ES8388_PDNVREFBUF_SHIFT       (0)
#define ES8388_PDNVREFBUF_BITMASK     (0x01 << ES8388_PDNVREFBUF_SHIFT)
#define ES8388_PDNVREFBUF_NORMAL      (0 << ES8388_PDNVREFBUF_SHIFT)
#define ES8388_PDNVREFBUF_PWRDN       (1 << ES8388_PDNVREFBUF_SHIFT)

#define ES8388_VREFLO_SHIFT           (1)
#define ES8388_VREFLO_BITMASK         (0x01 << ES8388_VREFLO_SHIFT)
#define ES8388_VREFLO_NORMAL          (0 << ES8388_VREFLO_SHIFT)
#define ES8388_VREFLO_LP              (1 << ES8388_VREFLO_SHIFT)

#define ES8388_PDNIBIASGEN_SHIFT      (2)
#define ES8388_PDNIBIASGEN_BITMASK    (0x01 << ES8388_PDNIBIASGEN_SHIFT)
#define ES8388_PDNIBIASGEN_NORMAL     (0 << ES8388_PDNIBIASGEN_SHIFT)
#define ES8388_PDNIBIASGEN_PWRDN      (1 << ES8388_PDNIBIASGEN_SHIFT)

#define ES8388_PDNANA_SHIFT           (3)
#define ES8388_PDNANA_BITMASK         (0x01 << ES8388_PDNANA_SHIFT)
#define ES8388_PDNANA_NORMAL          (0 << ES8388_PDNANA_SHIFT)
#define ES8388_PDNANA_PWRDN           (1 << ES8388_PDNANA_SHIFT)

#define ES8388_LPVREFBUF_SHIFT        (4)
#define ES8388_LPVREFBUF_BITMASK      (0x01 << ES8388_LPVREFBUF_SHIFT)
#define ES8388_LPVREFBUF_NORMAL       (0 << ES8388_LPVREFBUF_SHIFT)
#define ES8388_LPVREFBUF_LP           (1 << ES8388_LPVREFBUF_SHIFT)

#define ES8388_LPVCMMOD_SHIFT         (5)
#define ES8388_LPVCMMOD_BITMASK       (0x01 << ES8388_LPVCMMOD_SHIFT)
#define ES8388_LPVCMMOD_NORMAL        (0 << ES8388_LPVCMMOD_SHIFT)
#define ES8388_LPVCMMOD_LP            (1 << ES8388_LPVCMMOD_SHIFT)

/* 0x02 Chip Power Management */

#define ES8388_DACVREF_PDN_SHIFT      (0)
#define ES8388_DACVREF_PDN_BITMASK    (0x01 << ES8388_DACVREF_PDN_SHIFT)
#define ES8388_DACVREF_PDN_PWRUP      (0 << ES8388_DACVREF_PDN_SHIFT)
#define ES8388_DACVREF_PDN_PWRDN      (1 << ES8388_DACVREF_PDN_SHIFT)

#define ES8388_ADCVREF_PDN_SHIFT      (1)
#define ES8388_ADCVREF_PDN_BITMASK    (0x01 << ES8388_ADCVREF_PDN_SHIFT)
#define ES8388_ADCVREF_PDN_PWRUP      (0 << ES8388_ADCVREF_PDN_SHIFT)
#define ES8388_ADCVREF_PDN_PWRDN      (1 << ES8388_ADCVREF_PDN_SHIFT)

#define ES8388_DACDLL_PDN_SHIFT       (2)
#define ES8388_DACDLL_PDN_BITMASK     (0x01 << ES8388_DACDLL_PDN_SHIFT)
#define ES8388_DACDLL_PDN_NORMAL      (0 << ES8388_DACDLL_PDN_SHIFT)
#define ES8388_DACDLL_PDN_PWRDN       (1 << ES8388_DACDLL_PDN_SHIFT)

#define ES8388_ADCDLL_PDN_SHIFT       (3)
#define ES8388_ADCDLL_PDN_BITMASK     (0x01 << ES8388_ADCDLL_PDN_SHIFT)
#define ES8388_ADCDLL_PDN_NORMAL      (0 << ES8388_ADCDLL_PDN_SHIFT)
#define ES8388_ADCDLL_PDN_PWRDN       (1 << ES8388_ADCDLL_PDN_SHIFT)

#define ES8388_DAC_STM_RST_SHIFT      (4)
#define ES8388_DAC_STM_RST_BITMASK    (0x01 << ES8388_DAC_STM_RST_SHIFT)
#define ES8388_DAC_STM_RST_NORMAL     (0 << ES8388_DAC_STM_RST_SHIFT)
#define ES8388_DAC_STM_RST_RESET      (1 << ES8388_DAC_STM_RST_SHIFT)

#define ES8388_ADC_STM_RST_SHIFT      (5)
#define ES8388_ADC_STM_RST_BITMASK    (0x01 << ES8388_ADC_STM_RST_SHIFT)
#define ES8388_ADC_STM_RST_NORMAL     (0 << ES8388_ADC_STM_RST_SHIFT)
#define ES8388_ADC_STM_RST_RESET      (1 << ES8388_ADC_STM_RST_SHIFT)

#define ES8388_DAC_DIGPDN_SHIFT       (6)
#define ES8388_DAC_DIGPDN_BITMASK     (0x01 << ES8388_DAC_DIGPDN_SHIFT)
#define ES8388_DAC_DIGPDN_NORMAL      (0 << ES8388_DAC_DIGPDN_SHIFT)
#define ES8388_DAC_DIGPDN_RESET       (1 << ES8388_DAC_DIGPDN_SHIFT)

#define ES8388_ADC_DIGPDN_SHIFT       (7)
#define ES8388_ADC_DIGPDN_BITMASK     (0x01 << ES8388_ADC_DIGPDN_SHIFT)
#define ES8388_ADC_DIGPDN_NORMAL      (0 << ES8388_ADC_DIGPDN_SHIFT)
#define ES8388_ADC_DIGPDN_RESET       (1 << ES8388_ADC_DIGPDN_SHIFT)

/* 0x03 ADC Power Management */

#define ES8388_INT1LP_SHIFT           (0)
#define ES8388_INT1LP_BITMASK         (0x01 << ES8388_INT1LP_SHIFT)
#define ES8388_INT1LP_NORMAL          (0 << ES8388_INT1LP_SHIFT)
#define ES8388_INT1LP_LP              (1 << ES8388_INT1LP_SHIFT)

#define ES8388_FLASHLP_SHIFT          (1)
#define ES8388_FLASHLP_BITMASK        (0x01 << ES8388_FLASHLP_SHIFT)
#define ES8388_FLASHLP_NORMAL         (0 << ES8388_FLASHLP_SHIFT)
#define ES8388_FLASHLP_LP             (1 << ES8388_FLASHLP_SHIFT)

#define ES8388_PDNADCBIASGEN_SHIFT    (2)
#define ES8388_PDNADCBIASGEN_BITMASK  (0x01 << ES8388_PDNADCBIASGEN_SHIFT)
#define ES8388_PDNADCBIASGEN_NORMAL   (0 << ES8388_PDNADCBIASGEN_SHIFT)
#define ES8388_PDNADCBIASGEN_LP       (1 << ES8388_PDNADCBIASGEN_SHIFT)

#define ES8388_PDNMICB_SHIFT          (3)
#define ES8388_PDNMICB_BITMASK        (0x01 << ES8388_PDNMICB_SHIFT)
#define ES8388_PDNMICB_PWRON          (0 << ES8388_PDNMICB_SHIFT)
#define ES8388_PDNMICB_PWRDN          (1 << ES8388_PDNMICB_SHIFT)

#define ES8388_PDNADCR_SHIFT          (4)
#define ES8388_PDNADCR_BITMASK        (0x01 << ES8388_PDNADCR_SHIFT)
#define ES8388_PDNADCR_PWRUP          (0 << ES8388_PDNADCR_SHIFT)
#define ES8388_PDNADCR_PWRDN          (1 << ES8388_PDNADCR_SHIFT)

#define ES8388_PDNADCL_SHIFT          (5)
#define ES8388_PDNADCL_BITMASK        (0x01 << ES8388_PDNADCL_SHIFT)
#define ES8388_PDNADCL_PWRUP          (0 << ES8388_PDNADCL_SHIFT)
#define ES8388_PDNADCL_PWRDN          (1 << ES8388_PDNADCL_SHIFT)

#define ES8388_PDNAINR_SHIFT          (6)
#define ES8388_PDNAINR_BITMASK        (0x01 << ES8388_PDNAINR_SHIFT)
#define ES8388_PDNAINR_NORMAL         (0 << ES8388_PDNAINR_SHIFT)
#define ES8388_PDNAINR_PWRDN          (1 << ES8388_PDNAINR_SHIFT)

#define ES8388_PDNAINL_SHIFT          (7)
#define ES8388_PDNAINL_BITMASK        (0x01 << ES8388_PDNAINL_SHIFT)
#define ES8388_PDNAINL_NORMAL         (0 << ES8388_PDNAINL_SHIFT)
#define ES8388_PDNAINL_PWRDN          (1 << ES8388_PDNAINL_SHIFT)

/* 0x04 DAC Power Management */

#define ES8388_ROUT2_SHIFT            (2)
#define ES8388_ROUT2_BITMASK          (0x01 << ES8388_ROUT2_SHIFT)
#define ES8388_ROUT2_DISABLE          (0 << ES8388_ROUT2_SHIFT)
#define ES8388_ROUT2_ENABLE           (1 << ES8388_ROUT2_SHIFT)

#define ES8388_LOUT2_SHIFT            (3)
#define ES8388_LOUT2_BITMASK          (0x01 << ES8388_LOUT2_SHIFT)
#define ES8388_LOUT2_DISABLE          (0 << ES8388_LOUT2_SHIFT)
#define ES8388_LOUT2_ENABLE           (1 << ES8388_LOUT2_SHIFT)

#define ES8388_ROUT1_SHIFT            (4)
#define ES8388_ROUT1_BITMASK          (0x01 << ES8388_ROUT1_SHIFT)
#define ES8388_ROUT1_DISABLE          (0 << ES8388_ROUT1_SHIFT)
#define ES8388_ROUT1_ENABLE           (1 << ES8388_ROUT1_SHIFT)

#define ES8388_LOUT1_SHIFT            (5)
#define ES8388_LOUT1_BITMASK          (0x01 << ES8388_LOUT1_SHIFT)
#define ES8388_LOUT1_DISABLE          (0 << ES8388_LOUT1_SHIFT)
#define ES8388_LOUT1_ENABLE           (1 << ES8388_LOUT1_SHIFT)

#define ES8388_PDNDACR_SHIFT          (6)
#define ES8388_PDNDACR_BITMASK        (0x01 << ES8388_PDNDACR_SHIFT)
#define ES8388_PDNDACR_PWRUP          (0 << ES8388_PDNDACR_SHIFT)
#define ES8388_PDNDACR_PWRDN          (1 << ES8388_PDNDACR_SHIFT)

#define ES8388_PDNDACL_SHIFT          (7)
#define ES8388_PDNDACL_BITMASK        (0x01 << ES8388_PDNDACL_SHIFT)
#define ES8388_PDNDACL_PWRUP          (0 << ES8388_PDNDACL_SHIFT)
#define ES8388_PDNDACL_PWRDN          (1 << ES8388_PDNDACL_SHIFT)

/* 0x05 Chip Low Power 1 */

#define ES8388_LPLOUT2_SHIFT          (3)
#define ES8388_LPLOUT2_BITMASK        (0x01 << ES8388_LPLOUT2_SHIFT)
#define ES8388_LPLOUT2_NORMAL         (0 << ES8388_LPLOUT2_SHIFT)
#define ES8388_LPLOUT2_LP             (1 << ES8388_LPLOUT2_SHIFT)

#define ES8388_LPLOUT1_SHIFT          (5)
#define ES8388_LPLOUT1_BITMASK        (0x01 << ES8388_LPLOUT1_SHIFT)
#define ES8388_LPLOUT1_NORMAL         (0 << ES8388_LPLOUT1_SHIFT)
#define ES8388_LPLOUT1_LP             (1 << ES8388_LPLOUT1_SHIFT)

#define ES8388_LPDACR_SHIFT           (6)
#define ES8388_LPDACR_BITMASK         (0x01 << ES8388_LPDACR_SHIFT)
#define ES8388_LPDACR_NORMAL          (0 << ES8388_LPDACR_SHIFT)
#define ES8388_LPDACR_LP              (1 << ES8388_LPDACR_SHIFT)

#define ES8388_LPDACL_SHIFT           (7)
#define ES8388_LPDACL_BITMASK         (0x01 << ES8388_LPDACL_SHIFT)
#define ES8388_LPDACL_NORMAL          (0 << ES8388_LPDACL_SHIFT)
#define ES8388_LPDACL_LP              (1 << ES8388_LPDACL_SHIFT)

/* 0x06 Chip Low Power 2 */

#define ES8388_LPDACVRP_SHIFT         (0)
#define ES8388_LPDACVRP_BITMASK       (0x01 << ES8388_LPDACVRP_SHIFT)
#define ES8388_LPDACVRP_NORMAL        (0 << ES8388_LPDACVRP_SHIFT)
#define ES8388_LPDACVRP_LP            (1 << ES8388_LPDACVRP_SHIFT)

#define ES8388_LPADCVRP_SHIFT         (1)
#define ES8388_LPADCVRP_BITMASK       (0x01 << ES8388_LPDACVRP_SHIFT)
#define ES8388_LPADCVRP_NORMAL        (0 << ES8388_LPDACVRP_SHIFT)
#define ES8388_LPADCVRP_LP            (1 << ES8388_LPDACVRP_SHIFT)

#define ES8388_LPLMIX_SHIFT           (6)
#define ES8388_LPLMIX_BITMASK         (0x01 << ES8388_LPLMIX_SHIFT)
#define ES8388_LPLMIX_NORMAL          (0 << ES8388_LPLMIX_SHIFT)
#define ES8388_LPLMIX_LP              (1 << ES8388_LPLMIX_SHIFT)

#define ES8388_LPPGA_SHIFT            (7)
#define ES8388_LPPGA_BITMASK          (0x01 << ES8388_LPPGA_SHIFT)
#define ES8388_LPPGA_NORMAL           (0 << ES8388_LPPGA_SHIFT)
#define ES8388_LPPGA_LP               (1 << ES8388_LPPGA_SHIFT)

/* 0x08 Master Mode Control */

#define ES8388_BCLKDIV_SHIFT          (0)
#define ES8388_BCLKDIV_BITMASK        (0x1f << ES8388_BCLKDIV_SHIFT)
#define ES8388_BCLKDIV(a)             (a << ES8388_BCLKDIV_SHIFT)

#define ES8388_BCLK_INV_SHIFT         (5)
#define ES8388_BCLK_INV_BITMASL       (0x01 << ES8388_BCLK_INV_SHIFT)
#define ES8388_BCLK_INV_NORMAL        (0 << ES8388_BCLK_INV_SHIFT)
#define ES8388_BCLK_INV_INVERTED      (1 << ES8388_BCLK_INV_SHIFT)

#define ES8388_MCLKDIV2_SHIFT         (6)
#define ES8388_MCLKDIV2_BITMASK       (0x01 << ES8388_MCLKDIV2_SHIFT)
#define ES8388_MCLKDIV2_NODIV         (0 << ES8388_MCLKDIV2_SHIFT)
#define ES8388_MCLKDIV2_DIV2          (1 << ES8388_MCLKDIV2_SHIFT)

#define ES8388_MSC_SHIFT              (7)
#define ES8388_MSC_BITMASK            (0x01 << ES8388_MSC_SHIFT)
#define ES8388_MSC_SLAVE              (0 << ES8388_MSC_SHIFT)
#define ES8388_MSC_MASTER             (1 << ES8388_MSC_SHIFT)

/* 0x09 ADC Control 1 */

#define ES8388_MICAMPR_SHIFT          (0)
#define ES8388_MICAMPR_BITMASK        (0x0f << ES8388_MICAMPR_SHIFT)
#define ES8388_MICAMPR(a)             (a << ES8388_MICAMPR_SHIFT)

#define ES8388_MICAMPL_SHIFT          (4)
#define ES8388_MICAMPL_BITMASK        (0x0f << ES8388_MICAMPL_SHIFT)
#define ES8388_MICAMPL(a)             (a << ES8388_MICAMPL_SHIFT)

/* 0x0a ADC Control 2 */

#define ES8388_DSR_SHIFT              (2)
#define ES8388_DSR_BITMASK            (0x01 << ES8388_DSR_SHIFT)
#define ES8388_DSR_LINPUT1_RINPUT1    (0 << ES8388_DSR_SHIFT)
#define ES8388_DSR_LINPUT2_RINPUT2    (1 << ES8388_DSR_SHIFT)

#define ES8388_DSSEL_SHIFT            (3)
#define ES8388_DSSEL_BITMASK          (0x01 << ES8388_DSSEL_SHIFT)
#define ES8388_DSSEL_ONE_REG          (0 << ES8388_DSSEL_SHIFT)
#define ES8388_DSSEL_MULT_REG         (1 << ES8388_DSSEL_SHIFT)

#define ES8388_RINSEL_SHIFT           (4)
#define ES8388_RINSEL_BITMASK         (0x03 << ES8388_RINSEL_SHIFT)
#define ES8388_RINSEL_RINPUT1         (0 << ES8388_RINSEL_SHIFT)
#define ES8388_RINSEL_RINPUT2         (1 << ES8388_RINSEL_SHIFT)
#define ES8388_RINSEL_DIFF            (3 << ES8388_RINSEL_SHIFT)

#define ES8388_LINSEL_SHIFT           (6)
#define ES8388_LINSEL_BITMASK         (0x03 << ES8388_LINSEL_SHIFT)
#define ES8388_LINSEL_LINPUT1         (0 << ES8388_LINSEL_SHIFT)
#define ES8388_LINSEL_LINPUT2         (1 << ES8388_LINSEL_SHIFT)
#define ES8388_LINSEL_DIFF            (3 << ES8388_LINSEL_SHIFT)

/* 0x0b ADC Control 3 */

#define ES8388_TRI_SHIFT              (2)
#define ES8388_TRI_BITMASK            (0x01 << ES8388_TRI_SHIFT)
#define ES8388_TRI_NORMAL             (0 << ES8388_TRI_SHIFT)
#define ES8388_TRI_TRISTATED          (1 << ES8388_TRI_SHIFT)

#define ES8388_MONOMIX_SHIFT          (3)
#define ES8388_MONOMIX_BITMASK        (0x03 << ES8388_MONOMIX_SHIFT)
#define ES8388_MONOMIX_STEREO         (0 << ES8388_MONOMIX_SHIFT)
#define ES8388_MONOMIX_LADC           (1 << ES8388_MONOMIX_SHIFT)
#define ES8388_MONOMIX_RADC           (2 << ES8388_MONOMIX_SHIFT)

#define ES8388_DS_SHIFT               (7)
#define ES8388_DS_BITMASK             (0x01 << ES8388_DS_SHIFT)
#define ES8388_DS_LINPUT1_RINPUT1     (0 << ES8388_DS_SHIFT)
#define ES8388_DS_LINPUT2_RINPUT2     (1 << ES8388_DS_SHIFT)

/* 0x0c ADC Control 4 */

#define ES8388_ADCFORMAT_SHIFT        (0)
#define ES8388_ADCFORMAT_BITMASK      (0x03 << ES8388_ADCFORMAT_SHIFT)
#define ES8388_ADCFORMAT(a)           (a << ES8388_ADCFORMAT_SHIFT)

#define ES8388_ADCWL_SHIFT            (2)
#define ES8388_ADCWL_BITMASK          (0x07 << ES8388_ADCWL_SHIFT)
#define ES8388_ADCWL(a)               (a << ES8388_ADCWL_SHIFT)

#define ES8388_ADCLRP_SHIFT           (5)
#define ES8388_ADCLRP_BITMASK         (0x01 << ES8388_ADCLRP_SHIFT)
#define ES8388_ADCLRP_NORM_2ND        (0 << ES8388_ADCLRP_SHIFT)
#define ES8388_ADCLRP_INV_1ST         (1 << ES8388_ADCLRP_SHIFT)

#define ES8388_DATSEL_SHIFT           (6)
#define ES8388_DATSEL_BITMASK         (0x03 << ES8388_DATSEL_SHIFT)
#define ES8388_DATSEL_LL              (0 << ES8388_DATSEL_SHIFT)
#define ES8388_DATSEL_LR              (1 << ES8388_DATSEL_SHIFT)
#define ES8388_DATSEL_RR              (2 << ES8388_DATSEL_SHIFT)
#define ES8388_DATSEL_RL              (3 << ES8388_DATSEL_SHIFT)

/* 0x0d ADC Control 5 */

#define ES8388_ADCFSRATIO_SHIFT       (0)
#define ES8388_ADCFSRATIO_BITMASK     (0x1f << ES8388_ADCFSRATIO_SHIFT)
#define ES8388_ADCFSRATIO(a)          (a << ES8388_ADCFSRATIO_SHIFT)

#define ES8388_ADCFSMODE_SHIFT        (5)
#define ES8388_ADCFSMODE_BITMASK      (0x01 << ES8388_ADCFSMODE_SHIFT)
#define ES8388_ADCFSMODE_SINGLE       (0 << ES8388_ADCFSMODE_SHIFT)
#define ES8388_ADCFSMODE_DOUBLE       (1 << ES8388_ADCFSMODE_SHIFT)

/* 0x0e ADC Control 6 */

#define ES8388_ADC_HPF_R_SHIFT        (4)
#define ES8388_ADC_HPF_R_BITMASK      (0x01 << ES8388_ADC_HPF_R_SHIFT)
#define ES8388_ADC_HPF_R_DISABLE      (0 << ES8388_ADC_HPF_R_SHIFT)
#define ES8388_ADC_HPF_R_ENABLE       (1 << ES8388_ADC_HPF_R_SHIFT)

#define ES8388_ADC_HPF_L_SHIFT        (5)
#define ES8388_ADC_HPF_L_BITMASK      (0x01 << ES8388_ADC_HPF_L_SHIFT)
#define ES8388_ADC_HPF_L_DISABLE      (0 << ES8388_ADC_HPF_L_SHIFT)
#define ES8388_ADC_HPF_L_ENABLE       (1 << ES8388_ADC_HPF_L_SHIFT)

#define ES8388_ADC_INVR_SHIFT         (6)
#define ES8388_ADC_INVR_BITMASK       (0x01 << ES8388_ADC_INVR_SHIFT)
#define ES8388_ADC_INVR_NORMAL        (0 << ES8388_ADC_INVR_SHIFT)
#define ES8388_ADC_INVR_INVERTED      (1 << ES8388_ADC_INVR_SHIFT)

#define ES8388_ADC_INVL_SHIFT         (7)
#define ES8388_ADC_INVL_BITMASK       (0x01 << ES8388_ADC_INVL_SHIFT)
#define ES8388_ADC_INVL_NORMAL        (0 << ES8388_ADC_INVL_SHIFT)
#define ES8388_ADC_INVL_INVERTED      (1 << ES8388_ADC_INVL_SHIFT)

/* 0x0f ADC Control 7 */

#define ES8388_ADCMUTE_SHIFT          (2)
#define ES8388_ADCMUTE_BITMASK        (0x01 << ES8388_ADCMUTE_SHIFT)
#define ES8388_ADCMUTE(a)             (((int)a) << ES8388_ADCMUTE_SHIFT)
#define ES8388_ADCMUTE_NORMAL         (0 << ES8388_ADCMUTE_SHIFT)
#define ES8388_ADCMUTE_MUTED          (1 << ES8388_ADCMUTE_SHIFT)

#define ES8388_ADCLER_SHIFT           (3)
#define ES8388_ADCLER_BITMASK         (0x01 << ES8388_ADCLER_SHIFT)
#define ES8388_ADCLER_NORMAL          (0 << ES8388_ADCLER_SHIFT)
#define ES8388_ADCLER_ADCLEFT         (1 << ES8388_ADCLER_SHIFT)

#define ES8388_ADCSOFTRAMP_SHIFT      (5)
#define ES8388_ADCSOFTRAMP_BITMASK    (0x01 << ES8388_ADCSOFTRAMP_SHIFT)
#define ES8388_ADCSOFTRAMP_DISABLE    (0 << ES8388_ADCSOFTRAMP_SHIFT)
#define ES8388_ADCSOFTRAMP_ENABLE     (1 << ES8388_ADCSOFTRAMP_SHIFT)

#define ES8388_ADCRAMPRATE_SHIFT      (6)
#define ES8388_ADCRAMPRATE_BITMASK    (0x03 << ES8388_ADCRAMPRATE_SHIFT)
#define ES8388_ADCRAMPRATE_4LRCK      (0 << ES8388_ADCRAMPRATE_SHIFT)
#define ES8388_ADCRAMPRATE_8LRCK      (1 << ES8388_ADCRAMPRATE_SHIFT)
#define ES8388_ADCRAMPRATE_16LRCK     (2 << ES8388_ADCRAMPRATE_SHIFT)
#define ES8388_ADCRAMPRATE_32LRCK     (3 << ES8388_ADCRAMPRATE_SHIFT)

/* 0x10 ADC Control 8 */

#define ES8388_LADCVOL_SHIFT          (0)
#define ES8388_LADCVOL_BITMASK        (0xff << ES8388_LADCVOL_SHIFT)
#define ES8388_LADCVOL(a)             (a << ES8388_LADCVOL_SHIFT)

/* 0x11 ADC Control 9 */

#define ES8388_RADCVOL_SHIFT          (0)
#define ES8388_RADCVOL_BITMASK        (0xff << ES8388_RADCVOL_SHIFT)
#define ES8388_RADCVOL(a)             (a << ES8388_RADCVOL_SHIFT)

/* 0x12 ADC Control 10 */

#define ES8388_MINGAIN_SHIFT          (0)
#define ES8388_MINGAIN_BITMASK        (0x07 << ES8388_MINGAIN_SHIFT)
#define ES8388_MINGAIN(a)             (a << ES8388_MINGAIN_SHIFT)

#define ES8388_MAXGAIN_SHIFT          (3)
#define ES8388_MAXGAIN_BITMASK        (0x07 << ES8388_MAXGAIN_SHIFT)
#define ES8388_MAXGAIN(a)             (a << ES8388_MAXGAIN_SHIFT)

#define ES8388_ADCSEL_SHIFT           (6)
#define ES8388_ADCSEL_BITMASK         (0x03 << ES8388_ADCSEL_SHIFT)
#define ES8388_ADCSEL_OFF             (0 << ES8388_ADCSEL_SHIFT)
#define ES8388_ADCSEL_RIGHT           (1 << ES8388_ADCSEL_SHIFT)
#define ES8388_ADCSEL_LEFT            (2 << ES8388_ADCSEL_SHIFT)
#define ES8388_ADCSEL_STEREO          (3 << ES8388_ADCSEL_SHIFT)

/* 0x13 ADC Control 11 */

#define ES8388_ALCHLD_SHIFT           (0)
#define ES8388_ALCHLD_BITMASK         (0x0f << ES8388_ALCHLD_SHIFT)
#define ES8388_ALCHLD(a)              (a << ES8388_ALCHLD_SHIFT)

#define ES8388_ALCLVL_SHIFT           (4)
#define ES8388_ALCLVL_BITMASK         (0x0f << ES8388_ALCLVL_SHIFT)
#define ES8388_ALCLVL(a)              (a << ES8388_ALCLVL_SHIFT)

/* 0x14 ADC Control 12 */

#define ES8388_ALCATK_SHIFT           (0)
#define ES8388_ALCATK_BITMASK         (0x0f << ES8388_ALCATK_SHIFT)
#define ES8388_ALCATK(a)              (a << ES8388_ALCATK_SHIFT)

#define ES8388_ALCDCY_SHIFT           (4)
#define ES8388_ALCDCY_BITMASK         (0x0f << ES8388_ALCDCY_SHIFT)
#define ES8388_ALCDCY(a)              (a << ES8388_ALCDCY_SHIFT)

/* 0x15 ADC Control 13 */

#define ES8388_WIN_SIZE_SHIFT         (0)
#define ES8388_WIN_SIZE_BITMASK       (0x1f << ES8388_WIN_SIZE_SHIFT)
#define ES8388_WIN_SIZE(a)            (a << ES8388_WIN_SIZE_SHIFT)

#define ES8388_TIME_OUT_SHIFT         (5)
#define ES8388_TIME_OUT_BITMASK       (0x01 << ES8388_TIME_OUT_SHIFT)
#define ES8388_TIME_OUT_DISABLE       (0 << ES8388_TIME_OUT_SHIFT)
#define ES8388_TIME_OUT_ENABLE        (1 << ES8388_TIME_OUT_SHIFT)

#define ES8388_ALCZC_SHIFT            (6)
#define ES8388_ALCZC_BITMASK          (0x01 << ES8388_ALCZC_SHIFT)
#define ES8388_ALCZC_DISABLE          (0 << ES8388_ALCZC_SHIFT)
#define ES8388_ALCZC_ENABLE           (1 << ES8388_ALCZC_SHIFT)

#define ES8388_ALCMODE_SHIFT          (7)
#define ES8388_ALCMODE_BITMASK        (0x01 << ES8388_ALCMODE_SHIFT)
#define ES8388_ALCMODE_NORMAL         (0 << ES8388_ALCMODE_SHIFT)
#define ES8388_ALCMODE_LIMITER        (1 << ES8388_ALCMODE_SHIFT)

/* 0x16 ADC Control 14 */

#define ES8388_NGAT_SHIFT             (0)
#define ES8388_NGAT_BITMASK           (0x01 << ES8388_NGAT_SHIFT)
#define ES8388_NGAT_DISABLE           (0 << ES8388_NGAT_SHIFT)
#define ES8388_NGAT_ENABLE            (1 << ES8388_NGAT_SHIFT)

#define ES8388_NGG_SHIFT              (1)
#define ES8388_NGG_BITMASK            (0x01 << ES8388_NGG_SHIFT)
#define ES8388_NGG_CONST              (0 << ES8388_NGG_SHIFT)
#define ES8388_NGG_MUTE               (1 << ES8388_NGG_SHIFT)

#define ES8388_NGTH_SHIFT             (3)
#define ES8388_NGTH_BITMASK           (0x1f << ES8388_NGTH_SHIFT)
#define ES8388_NGTH(a)                (a << ES8388_NGTH_SHIFT)

/* 0x17 DAC Control 1 */

#define ES8388_DACFORMAT_SHIFT        (1)
#define ES8388_DACFORMAT_BITMASK      (0x03 << ES8388_DACFORMAT_SHIFT)
#define ES8388_DACFORMAT(a)           (a << ES8388_DACFORMAT_SHIFT)

#define ES8388_DACWL_SHIFT            (3)
#define ES8388_DACWL_BITMASK          (0x07 << ES8388_DACWL_SHIFT)
#define ES8388_DACWL(a)               (a << ES8388_DACWL_SHIFT)

#define ES8388_DACLRP_SHIFT           (6)
#define ES8388_DACLRP_BITMASK         (0x01 << ES8388_DACLRP_SHIFT)
#define ES8388_DACLRP_NORM_2ND        (0 << ES8388_DACLRP_SHIFT)
#define ES8388_DACLRP_INV_1ST         (1 << ES8388_DACLRP_SHIFT)

#define ES8388_DACLRSWAP_SHIFT        (7)
#define ES8388_DACLRSWAP_BITMASK      (0x01 << ES8388_DACLRSWAP_SHIFT)
#define ES8388_DACLRSWAP_NORMAL       (0 << ES8388_DACLRSWAP_SHIFT)
#define ES8388_DACLRSWAP_SWAP         (1 << ES8388_DACLRSWAP_SHIFT)

/* 0x18 DAC Control 2 */

#define ES8388_DACFSRATIO_SHIFT       (0)
#define ES8388_DACFSRATIO_BITMASK     (0x1f << ES8388_DACFSRATIO_SHIFT)
#define ES8388_DACFSRATIO(a)          (a << ES8388_DACFSRATIO_SHIFT)

#define ES8388_DACFSMODE_SHIFT        (5)
#define ES8388_DACFSMODE_BITMASK      (0x01 << ES8388_DACFSMODE_SHIFT)
#define ES8388_DACFSMODE_SINGLE       (0 << ES8388_DACFSMODE_SHIFT)
#define ES8388_DACFSMODE_DOUBLE       (1 << ES8388_DACFSMODE_SHIFT)

/* 0x19 DAC Control 3 */

#define ES8388_DACMUTE_SHIFT          (2)
#define ES8388_DACMUTE_BITMASK        (0x01 << ES8388_DACMUTE_SHIFT)
#define ES8388_DACMUTE(a)             (((int)a) << ES8388_DACMUTE_SHIFT)
#define ES8388_DACMUTE_NORMAL         (0 << ES8388_DACMUTE_SHIFT)
#define ES8388_DACMUTE_MUTED          (1 << ES8388_DACMUTE_SHIFT)

#define ES8388_DACLER_SHIFT           (3)
#define ES8388_DACLER_BITMASK         (0x01 << ES8388_DACLER_SHIFT)
#define ES8388_DACLER_NORMAL          (0 << ES8388_DACLER_SHIFT)
#define ES8388_DACLER_ADCLEFT         (1 << ES8388_DACLER_SHIFT)

#define ES8388_DACSOFTRAMP_SHIFT      (5)
#define ES8388_DACSOFTRAMP_BITMASK    (0x01 << ES8388_DACSOFTRAMP_SHIFT)
#define ES8388_DACSOFTRAMP_DISABLE    (0 << ES8388_DACSOFTRAMP_SHIFT)
#define ES8388_DACSOFTRAMP_ENABLE     (1 << ES8388_DACSOFTRAMP_SHIFT)

#define ES8388_DACRAMPRATE_SHIFT      (6)
#define ES8388_DACRAMPRATE_BITMASK    (0x03 << ES8388_DACRAMPRATE_SHIFT)
#define ES8388_DACRAMPRATE_4LRCK      (0 << ES8388_DACRAMPRATE_SHIFT)
#define ES8388_DACRAMPRATE_32LRCK     (1 << ES8388_DACRAMPRATE_SHIFT)
#define ES8388_DACRAMPRATE_64LRCK     (2 << ES8388_DACRAMPRATE_SHIFT)
#define ES8388_DACRAMPRATE_128LRCK    (3 << ES8388_DACRAMPRATE_SHIFT)

/* 0x1a DAC Control 4 */

#define ES8388_LDACVOL_SHIFT          (0)
#define ES8388_LDACVOL_BITMASK        (0xff << ES8388_LDACVOL_SHIFT)
#define ES8388_LDACVOL(a)             (a << ES8388_LDACVOL_SHIFT)

/* 0x1b DAC Control 5 */

#define ES8388_RDACVOL_SHIFT          (0)
#define ES8388_RDACVOL_BITMASK        (0xff << ES8388_RDACVOL_SHIFT)
#define ES8388_RDACVOL(a)             (a << ES8388_RDACVOL_SHIFT)

/* 0x1c DAC Control 6 */

#define ES8388_CLICKFREE_SHIFT        (3)
#define ES8388_CLICKFREE_BITMASK      (0x01 << ES8388_CLICKFREE_SHIFT)
#define ES8388_CLICKFREE_DISABLE      (0 << ES8388_CLICKFREE_SHIFT)
#define ES8388_CLICKFREE_ENABLE       (1 << ES8388_CLICKFREE_SHIFT)

#define ES8388_DAC_INVR_SHIFT         (4)
#define ES8388_DAC_INVR_BITMASK       (0x01 << ES8388_DAC_INVR_SHIFT)
#define ES8388_DAC_INVR_NOINV         (0 << ES8388_DAC_INVR_SHIFT)
#define ES8388_DAC_INVR_180INV        (1 << ES8388_DAC_INVR_SHIFT)

#define ES8388_DAC_INVL_SHIFT         (5)
#define ES8388_DAC_INVL_BITMASK       (0x01 << ES8388_DAC_INVL_SHIFT)
#define ES8388_DAC_INVL_NOINV         (0 << ES8388_DAC_INVL_SHIFT)
#define ES8388_DAC_INVL_180INV        (1 << ES8388_DAC_INVL_SHIFT)

#define ES8388_DEEMP_SHIFT            (6)
#define ES8388_DEEMP_BITMASK          (0x03 << ES8388_DEEMP_SHIFT)
#define ES8388_DEEMP_DISABLE          (0 << ES8388_DEEMP_SHIFT)
#define ES8388_DEEMP_32KHZ            (1 << ES8388_DEEMP_SHIFT)
#define ES8388_DEEMP_44KHZ            (2 << ES8388_DEEMP_SHIFT)
#define ES8388_DEEMP_48KHZ            (3 << ES8388_DEEMP_SHIFT)

/* 0x1d DAC Control 7 */

#define ES8388_VPP_SCALE_SHIFT        (0)
#define ES8388_VPP_SCALE_BITMASK      (0x03 << ES8388_VPP_SCALE_SHIFT)
#define ES8388_VPP_SCALE_3_5V         (0 << ES8388_VPP_SCALE_SHIFT)
#define ES8388_VPP_SCALE_4_0V         (1 << ES8388_VPP_SCALE_SHIFT)
#define ES8388_VPP_SCALE_3_0V         (2 << ES8388_VPP_SCALE_SHIFT)
#define ES8388_VPP_SCALE_2_5V         (3 << ES8388_VPP_SCALE_SHIFT)

#define ES8388_SE_SHIFT               (2)
#define ES8388_SE_BITMASK             (0x07 << ES8388_SE_SHIFT)
#define ES8388_SE(a)                  (a << ES8388_SE_SHIFT)

#define ES8388_MONO_SHIFT             (5)
#define ES8388_MONO_BITMASK           (0x01 << ES8388_MONO_SHIFT)
#define ES8388_MONO_STEREO            (0 << ES8388_MONO_SHIFT)
#define ES8388_MONO_MONO              (1 << ES8388_MONO_SHIFT)

#define ES8388_ZEROR_SHIFT            (6)
#define ES8388_ZEROR_BITMASK          (0x01 << ES8388_ZEROR_SHIFT)
#define ES8388_ZEROR_NORMAL           (0 << ES8388_ZEROR_SHIFT)
#define ES8388_ZEROR_ZERO             (1 << ES8388_ZEROR_SHIFT)

#define ES8388_ZEROL_SHIFT            (7)
#define ES8388_ZEROL_BITMASK          (0x01 << ES8388_ZEROL_SHIFT)
#define ES8388_ZEROL_NORMAL           (0 << ES8388_ZEROL_SHIFT)
#define ES8388_ZEROL_ZERO             (1 << ES8388_ZEROL_SHIFT)

/* 0x1e DAC Control 8
 * 0x1f DAC Control 9
 * 0x20 DAC Control 10
 * 0x21 DAC Control 11
 * 0x22 DAC Control 12
 * 0x23 DAC Control 13
 * 0x24 DAC Control 14
 * 0x25 DAC Control 15
 */

#define ES8388_SHELVING_COEF_SHIFT    (0)
#define ES8388_SHELVING_COEF_BITMASK  (0xff << ES8388_SHELVING_COEF_SHIFT)
#define ES8388_SHELVING_COEF(a)       (a << ES8388_SHELVING_COEF_SHIFT)

/* 0x26 DAC Control 16 */

#define ES8388_RMIXSEL_SHIFT          (0)
#define ES8388_RMIXSEL_BITMASK        (0x07 << ES8388_RMIXSEL_SHIFT)
#define ES8388_RMIXSEL_RIN1           (0 << ES8388_RMIXSEL_SHIFT)
#define ES8388_RMIXSEL_RIN2           (1 << ES8388_RMIXSEL_SHIFT)
#define ES8388_RMIXSEL_PIN            (3 << ES8388_RMIXSEL_SHIFT)
#define ES8388_RMIXSEL_NIN            (4 << ES8388_RMIXSEL_SHIFT)

#define ES8388_LMIXSEL_SHIFT          (3)
#define ES8388_LMIXSEL_BITMASK        (0x07 << ES8388_LMIXSEL_SHIFT)
#define ES8388_LMIXSEL_LIN1           (0 << ES8388_LMIXSEL_SHIFT)
#define ES8388_LMIXSEL_LIN2           (1 << ES8388_LMIXSEL_SHIFT)
#define ES8388_LMIXSEL_PIN            (3 << ES8388_LMIXSEL_SHIFT)
#define ES8388_LMIXSEL_NIN            (4 << ES8388_LMIXSEL_SHIFT)

/* 0x27 DAC Control 17 */

#define ES8388_LI2LOVOL_SHIFT         (3)
#define ES8388_LI2LOVOL_BITMASK       (0x07 << ES8388_LI2LOVOL_SHIFT)
#define ES8388_LI2LOVOL(a)            (a << ES8388_LI2LOVOL_SHIFT)

#define ES8388_LI2LO_SHIFT            (6)
#define ES8388_LI2LO_BITMASK          (0x01 << ES8388_LI2LO_SHIFT)
#define ES8388_LI2LO_DISABLE          (0 << ES8388_LI2LO_SHIFT)
#define ES8388_LI2LO_ENABLE           (1 << ES8388_LI2LO_SHIFT)

#define ES8388_LD2LO_SHIFT            (7)
#define ES8388_LD2LO_BITMASK          (0x01 << ES8388_LD2LO_SHIFT)
#define ES8388_LD2LO_DISABLE          (0 << ES8388_LD2LO_SHIFT)
#define ES8388_LD2LO_ENABLE           (1 << ES8388_LD2LO_SHIFT)

/* 0x2a DAC Control 20 */

#define ES8388_RI2ROVOL_SHIFT         (3)
#define ES8388_RI2ROVOL_BITMASK       (0x07 << ES8388_RI2ROVOL_SHIFT)
#define ES8388_RI2ROVOL(a)            (a << ES8388_RI2ROVOL_SHIFT)

#define ES8388_RI2RO_SHIFT            (6)
#define ES8388_RI2RO_BITMASK          (0x01 << ES8388_RI2RO_SHIFT)
#define ES8388_RI2RO_DISABLE          (0 << ES8388_RI2RO_SHIFT)
#define ES8388_RI2RO_ENABLE           (1 << ES8388_RI2RO_SHIFT)

#define ES8388_RD2RO_SHIFT            (7)
#define ES8388_RD2RO_BITMASK          (0x01 << ES8388_RD2RO_SHIFT)
#define ES8388_RD2RO_DISABLE          (0 << ES8388_RD2RO_SHIFT)
#define ES8388_RD2RO_ENABLE           (1 << ES8388_RD2RO_SHIFT)

/* 0x2b DAC Control 21 */

#define ES8388_DAC_DLL_PWD_SHIFT      (2)
#define ES8388_DAC_DLL_PWD_BITMASK    (0x01 << ES8388_DAC_DLL_PWD_SHIFT)
#define ES8388_DAC_DLL_PWD_NORMAL     (0 << ES8388_DAC_DLL_PWD_SHIFT)
#define ES8388_DAC_DLL_PWD_PWRDN      (1 << ES8388_DAC_DLL_PWD_SHIFT)

#define ES8388_ADC_DLL_PWD_SHIFT      (3)
#define ES8388_ADC_DLL_PWD_BITMASK    (0x01 << ES8388_ADC_DLL_PWD_SHIFT)
#define ES8388_ADC_DLL_PWD_NORMAL     (0 << ES8388_ADC_DLL_PWD_SHIFT)
#define ES8388_ADC_DLL_PWD_PWRDN      (1 << ES8388_ADC_DLL_PWD_SHIFT)

#define ES8388_MCLK_DIS_SHIFT         (4)
#define ES8388_MCLK_DIS_BITMASK       (0x01 << ES8388_MCLK_DIS_SHIFT)
#define ES8388_MCLK_DIS_NORMAL        (0 << ES8388_MCLK_DIS_SHIFT)
#define ES8388_MCLK_DIS_DISABLE       (1 << ES8388_MCLK_DIS_SHIFT)

#define ES8388_OFFSET_DIS_SHIFT       (5)
#define ES8388_OFFSET_DIS_BITMASK     (0x01 << ES8388_OFFSET_DIS_SHIFT)
#define ES8388_OFFSET_DIS_DISABLE     (0 << ES8388_OFFSET_DIS_SHIFT)
#define ES8388_OFFSET_DIS_ENABLE      (1 << ES8388_OFFSET_DIS_SHIFT)

#define ES8388_LRCK_SEL_SHIFT         (6)
#define ES8388_LRCK_SEL_BITMASK       (0x01 << ES8388_LRCK_SEL_SHIFT)
#define ES8388_LRCK_SEL_DAC           (0 << ES8388_LRCK_SEL_SHIFT)
#define ES8388_LRCK_SEL_ADC           (1 << ES8388_LRCK_SEL_SHIFT)

#define ES8388_SLRCK_SHIFT            (7)
#define ES8388_SLRCK_BITMASK          (0x01 << ES8388_SLRCK_SHIFT)
#define ES8388_SLRCK_SEPARATE         (0 << ES8388_SLRCK_SHIFT)
#define ES8388_SLRCK_SAME             (1 << ES8388_SLRCK_SHIFT)

/* 0x2c DAC Control 22 */

#define ES8388_OFFSET_SHIFT           (0)
#define ES8388_OFFSET_BITMASK         (0xff << ES8388_OFFSET_SHIFT)
#define ES8388_OFFSET(a)              (a << ES8388_OFFSET_SHIFT)

/* 0x2d DAC Control 23 */

#define ES8388_VROI_SHIFT             (4)
#define ES8388_VROI_BITMASK           (0x01 << ES8388_VROI_SHIFT)
#define ES8388_VROI_1_5K              (0 << ES8388_VROI_SHIFT)
#define ES8388_VROI_40K               (1 << ES8388_VROI_SHIFT)

/* 0x2e DAC Control 24 */

#define ES8388_LOUT1VOL_SHIFT         (0)
#define ES8388_LOUT1VOL_BITMASK       (0x3f << ES8388_LOUT1VOL_SHIFT)
#define ES8388_LOUT1VOL(a)            (a << ES8388_LOUT1VOL_SHIFT)

/* 0x2f DAC Control 25 */

#define ES8388_ROUT1VOL_SHIFT         (0)
#define ES8388_ROUT1VOL_BITMASK       (0x3f << ES8388_ROUT1VOL_SHIFT)
#define ES8388_ROUT1VOL(a)            (a << ES8388_ROUT1VOL_SHIFT)

/* 0x30 DAC Control 26 */

#define ES8388_LOUT2VOL_SHIFT         (0)
#define ES8388_LOUT2VOL_BITMASK       (0x3f << ES8388_LOUT2VOL_SHIFT)
#define ES8388_LOUT2VOL(a)            (a << ES8388_LOUT2VOL_SHIFT)

/* 0x31 DAC Control 27 */

#define ES8388_ROUT2VOL_SHIFT         (0)
#define ES8388_ROUT2VOL_BITMASK       (0x3f << ES8388_ROUT2VOL_SHIFT)
#define ES8388_ROUT2VOL(a)            (a << ES8388_ROUT2VOL_SHIFT)

/* Codec Default Parameters *************************************************/

#define ES8388_DEFAULT_SAMPRATE      44100
#define ES8388_DEFAULT_NCHANNELS     2
#define ES8388_DEFAULT_BPSAMP        16

/****************************************************************************
 * Public Types
 ****************************************************************************/

typedef enum
{
  ES8388_DAC_OUTPUT_LINE1,
  ES8388_DAC_OUTPUT_LINE2,
  ES8388_DAC_OUTPUT_ALL,
} es8388_dac_output_e;

typedef enum
{
  ES8388_ADC_INPUT_LINE1,
  ES8388_ADC_INPUT_LINE2,
  ES8388_ADC_INPUT_ALL,
  ES8388_ADC_INPUT_DIFFERENCE,
} es8388_adc_input_e;

typedef enum
{
  ES8388_MIXER_GAIN_6DB,
  ES8388_MIXER_GAIN_3DB,
  ES8388_MIXER_GAIN_0DB,
  ES8388_MIXER_GAIN_N3DB,
  ES8388_MIXER_GAIN_N6DB,
  ES8388_MIXER_GAIN_N9DB,
  ES8388_MIXER_GAIN_N12DB,
  ES8388_MIXER_GAIN_N15DB,
} es8388_mixer_gain_e;

struct mclk_rate_s
{
  uint32_t mclk;
  uint32_t sample_rate;
  uint16_t multiple;
};

struct es8388_dev_s
{
  /* We are an audio lower half driver (We are also the upper "half" of
   * the ES8388 driver with respect to the board lower half driver).
   *
   * Terminology:
   * Our "lower" half audio instances will be called dev for the publicly
   * visible version and "priv" for the version that only this driver knows
   * From the point of view of this driver, it is the board lower "half"
   * that is referred to as "lower".
   */

  struct audio_lowerhalf_s            dev;              /* ES8388 audio lower half (this device) */

  FAR const struct es8388_lower_s    *lower;            /* Pointer to the board lower functions */
  FAR struct i2c_master_s            *i2c;              /* I2C driver to use */
  FAR struct i2s_dev_s               *i2s;              /* I2S driver to use */
  struct dq_queue_s                   pendq;            /* Queue of pending buffers to be processed */
  struct dq_queue_s                   doneq;            /* Queue of sent buffers to be returned */
  struct file                         mq;               /* Message queue for receiving messages */
  char                                mqname[NAME_MAX]; /* Our message queue name */
  pthread_t                           threadid;         /* ID of our thread */
  mutex_t                             pendlock;         /* Protect pendq */
  uint32_t                            samprate;         /* Configured samprate (samples/sec) */
#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
#ifndef CONFIG_AUDIO_EXCLUDE_BALANCE
  uint16_t                            balance;          /* Current balance level {0..1000} */
#endif /* CONFIG_AUDIO_EXCLUDE_BALANCE */
  uint16_t                            volume_out;       /* Current output volume level {0..1000} */
  uint16_t                            volume_in;        /* Current input volume level {0..1000} */
#endif /* CONFIG_AUDIO_EXCLUDE_VOLUME */
  uint8_t                             nchannels;        /* Number of channels (1 or 2) */
  uint8_t                             bpsamp;           /* Bits per sample */
  volatile uint8_t                    inflight;         /* Number of audio buffers in-flight */
  bool                                running;          /* True: Worker thread is running */
  bool                                paused;           /* True: Playing is paused */
  bool                                mute;             /* True: Output is muted */
#ifndef CONFIG_AUDIO_EXCLUDE_STOP
  bool                                terminating;      /* True: Stop requested */
#endif
  bool                                reserved;         /* True: Device is reserved */
  volatile int                        result;           /* The result of the last transfer */
  es_module_e                         audio_mode;       /* The current audio mode of the ES8388 chip */
  es8388_dac_output_e                 dac_output;       /* The current output of the ES8388 DAC */
  es8388_adc_input_e                  adc_input;        /* The current input of the ES8388 ADC */
  es_mic_gain_e                       mic_gain;         /* The current microphone gain */
  uint32_t                            mclk;             /* The current MCLK frequency */
};

/****************************************************************************
 * Public Data
 ****************************************************************************/

static const struct mclk_rate_s es8388_mclk_rate[] =
{
  /* 8kHz support is board dependent */

  /* 12.288 MHz */

  {
    12288000, /* mclk        */
    12000,    /* sample_rate */
    1024,     /* multiple    */
  },
  {
    12288000, /* mclk        */
    16000,    /* sample_rate */
    768,      /* multiple    */
  },
  {
    12288000, /* mclk        */
    24000,    /* sample_rate */
    512,      /* multiple    */
  },
  {
    12288000, /* mclk        */
    32000,    /* sample_rate */
    384,      /* multiple    */
  },
  {
    12288000, /* mclk        */
    48000,    /* sample_rate */
    256,      /* multiple    */
  },

  /* 11.2896 MHz */

  {
    11289600, /* mclk        */
    11025,    /* sample_rate */
    1024      /* multiple    */
  },
  {
    11289600, /* mclk        */
    22050,    /* sample_rate */
    512       /* multiple    */
  },
  {
    11289600, /* mclk        */
    44100,    /* sample_rate */
    256       /* multiple    */
  },
};

/****************************************************************************
 * Public Function Prototypes
 ****************************************************************************/

/****************************************************************************
 * Name: es8388_readreg
 *
 * Description:
 *    Read the specified 8-bit register from the ES8388 device.
 *
 ****************************************************************************/

#if defined(CONFIG_ES8388_REGDUMP)
struct es8388_dev_s;
uint8_t es8388_readreg(FAR struct es8388_dev_s *priv, uint8_t regaddr);
#endif

#endif /* CONFIG_AUDIO */
#endif /* __DRIVERS_AUDIO_ES8388_H */
